#include <stdio.h>
#include <thread>
#include <chrono>

#include "nlohmann/json.hpp"
#include "base_time_cost.h"
#include "base_log.h"
#include "base_init.h"
#include "common_init.h"
#include "media_init.h"
#include "storage_init.h"
#include "event_init.h"
#include "record_init.h"
#include "stream_server_init.h"
#include "web_server_init.h"
#include "cloud_model_init.h"
#include "hal_init.h"
#include "common_version.h"
#include "upgrade.h"
#include "restful_init.h"
#include "system_server.h"
#include "common_version.h"
#include "common_product_definition.h"
#include "protocol_init.h"

int main(int argc, char **argv)
{
    (void)argc;
    (void)argv;
    // 初始化基础库
    El::Base::TimeCost time_cost("main", true);
    nlohmann::json config;
    // config["log_file"] = "/mnt/log/app.log";
    // config["log_max_size"] = 2 * 1024 * 1024 / 3;
    // config["log_max_files"] = 2;
    config["log_level"] = "info";
    config["log_to_file"] = false;
    El::Base::base_init(config);
    time_cost.Mark("base_init");

    // 初始化公共组件
    config.clear();
    config["general"] = "/mnt/config/config";
    config["default"] = "/mnt/config/default";
    config["product"] = "/app/custom/product.yaml";
    El::Common::common_init(config);
    time_cost.Mark("common_init");

    // 打印产品信息
    std::string device_model;
    std::string serial_number;
    El::Common::ProductDefinition::GetInstance().GetValue("device_model", device_model);
    El::Common::ProductDefinition::GetInstance().GetValue("serial_number", serial_number);
    LOG_INFO("main start product:{} serial:{} version:{}", device_model.c_str(), serial_number.c_str(),
             El::Common::VersionManager::GetInstance().GetVersionFull().c_str());

    // 初始化hal
    config.clear();
    hal_init(config);
    time_cost.Mark("hal_init");

    // 初始化系统服务
    config.clear();
    El::SystemServer::SystemServer::GetInstance().Start();
    time_cost.Mark("system_server_init");

    // 初始化事件
    config.clear();
    config["db_path"] = "/mnt/data/event.db";
    config["db_size"] = 1024 * 1024 * 1024;
    config["db_max_open_files"] = 100;
    config["max_events"] = 1000;
    El::Event::event_init(config);
    time_cost.Mark("event_init");

    // 初始化升级
    if (!El::Upgrade::Upgrade::GetInstance().Start()) {
        LOG_ERROR("Upgrade process failed to start.");
    }
    time_cost.Mark("upgrade_init");

    // 初始化音视频流
    config.clear();
    El::Media::stream_init(config);
    time_cost.Mark("stream_init");

    // 初始化存储
    config.clear();
    El::Storage::storage_init(config);
    time_cost.Mark("storage_init");

    // 初始化录像
    config.clear();
    El::Record::record_init(config);
    time_cost.Mark("record_init");

    // 启动流媒体服务
    config.clear();
    El::StreamServer::stream_server_init(config);
    time_cost.Mark("stream_server_init");

    // 启动web服务
    config.clear();
    config["web_dir"] = "/app/web";
    El::WebServer::web_server_init(config);
    time_cost.Mark("web_server_init");

    // 启动restful服务
    config.clear();
    El::Restful::restful_init(config);
    time_cost.Mark("restful_init");

    // 初始化协议服务
    config.clear();
    El::Protocol::protocol_init(config);
    time_cost.Mark("protocol_init");

    // 初始化云端大模型
    config.clear();
    El::Cloud::cloud_model_init(config);
    time_cost.Mark("cloud_model_init");
    time_cost.Print();

    // 用条件变量阻塞
    std::mutex mutex;
    std::unique_lock<std::mutex> lock(mutex);
    std::condition_variable cond;
    cond.wait(lock);

    return 0;
}